package com.jungle.base.dao;

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
import org.springframework.data.domain.Limit;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;
import org.springframework.data.repository.NoRepositoryBean;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Stream;

/**
 * @author Administrator
 */
@NoRepositoryBean
public interface ExtendedJpaRepository<T, ID> extends JpaRepositoryImplementation<T, ID> {

    ID getId(T entity);

    void persist(T entity);

    T merge(T entity);

    /**
     * 查询返回集合
     *
     * @param consumer 处理函数
     * @return 结果集合
     */
    List<T> getResultList(BiConsumer<CriteriaBuilder, CriteriaQuery<T>> consumer);

    /**
     * 查询返回单一对象
     *
     * @param consumer 处理函数
     * @return 结果对象
     */
    T getSingleResult(BiConsumer<CriteriaBuilder, CriteriaQuery<T>> consumer);

    /**
     * 查询返回流对象
     *
     * @param consumer 处理函数
     * @return 结果集合流
     */
    Stream<T> getResultStream(BiConsumer<CriteriaBuilder, CriteriaQuery<T>> consumer);

    /**
     * 更新操作
     *
     * @param consumer 处理函数
     * @return 更新数据条数
     */
    int executeUpdate(BiConsumer<CriteriaBuilder, CriteriaUpdate<T>> consumer);

    /**
     * 删除操作
     *
     * @param consumer 处理函数
     * @return 删除数据条数
     */
    int executeDelete(BiConsumer<CriteriaBuilder, CriteriaDelete<T>> consumer);

    /**
     * Finds a single entity that matches the given specification and sort order.
     * <p>
     * This method searches for an entity that satisfies the provided specification criteria
     * and returns it sorted according to the specified sort order. If no entity matches the
     * criteria, the method may return null or throw an exception, depending on the implementation.
     *
     * @param specification The specification criteria to match the entity.
     * @param sort          The sort order to apply when retrieving the entity.
     * @return The found entity, or null if no matching entity is found.
     */
    T findOne(Specification<T> specification, Sort sort);


    /**
     * Finds all entities that match the given specification, limit, and sort orders.
     *
     * @param specification The specification to match entities against.
     * @param limit         The limit to apply to the query results, useful for pagination.
     * @param sort          Varargs parameter defining the order of the query results.
     * @return A list of entities that match the given criteria.
     */
    List<T> findAll(Specification<T> specification, Sort sort, Limit limit);

}
